home *** CD-ROM | disk | FTP | other *** search
/ EnigmA Amiga Run 1997 April / EnigmA AMIGA RUN 17 (1997)(G.R. Edizioni)(IT)[!][issue 1997-04][EAR-CD].iso / EARCD / text / hyper / hsc_source.lha / hsc / source / hsclib / skip.c < prev    next >
C/C++ Source or Header  |  1996-11-15  |  16KB  |  551 lines

  1. /*
  2.  * skip.c
  3.  *
  4.  * functions for skipping several things
  5.  *
  6.  * Copyright (C) 1995,96 Thomas Aglassinger
  7.  *
  8.  * This program is free software; you can redistribute it and/or modify
  9.  * it under the terms of the GNU General Public License as published by
  10.  * the Free Software Foundation; either version 2 of the License, or
  11.  * (at your option) any later version.
  12.  *
  13.  * This program is distributed in the hope that it will be useful,
  14.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  16.  * GNU General Public License for more details.
  17.  *
  18.  * You should have received a copy of the GNU General Public License
  19.  * along with this program; if not, write to the Free Software
  20.  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  21.  *
  22.  * updated: 30-Oct-1996
  23.  * created:  8-Oct-1995
  24.  */
  25.  
  26. #define NOEXTERN_HSCLIB_SKIP_H
  27.  
  28. #include "hsclib/inc_base.h"
  29.  
  30. #include "hsclib/input.h"
  31. #include "hsclib/skip.h"
  32.  
  33. /* debug skip */
  34. #if 1
  35. #define DS(x) if(hp->debug) x
  36. #else
  37. #define DS(x)
  38. #endif
  39. #define DHLS "*hsclib* skip: "
  40.  
  41. /*
  42.  * skip_next_lf
  43.  *
  44.  * ignore '\n'
  45.  *
  46.  * params: inpf...input file to read char from
  47.  * result: TRUE if skipped
  48.  */
  49. BOOL skip_next_lf(HSCPRC * hp)
  50. {
  51.     /* TODO: skip white-spaces after linefeed,
  52.      * if COMPACT set; but this has to be performed
  53.      * at another part of the code... */
  54.     INFILE *inpf = hp->inpf;
  55.  
  56.     int nc = infgetc(inpf);
  57.  
  58.     if (nc != '\n')
  59.         inungetc(nc, inpf);
  60.  
  61.     return ((BOOL) (nc == EOF));
  62. }
  63.  
  64. BOOL eot_reached(HSCPRC * hp, BYTE * state)
  65. {
  66.     INFILE *inpf = hp->inpf;
  67.     STRPTR nw = infgetw(inpf);
  68.  
  69.     if (nw)
  70.     {
  71.         switch (*state)
  72.         {
  73.         case TGST_TAG:
  74.             if (!strcmp(nw, "\""))
  75.                 *state = TGST_DQUOTE;
  76.             else if (!strcmp(nw, "'"))
  77.                 *state = TGST_QUOTE;
  78. /* TODO: skip references & expressions */
  79. #if 0
  80.             else if (!strcmp(nw, "<"))
  81.                 *state = TGST_REF;
  82. #endif
  83.             else if (!strcmp(nw, ">"))
  84.                 *state = TGST_END;
  85.             break;
  86.  
  87.         case TGST_REF:
  88.         case TGST_QUOTE:
  89.         case TGST_DQUOTE:
  90.  
  91.             if (strcmp(nw, "\n"))
  92.             {
  93.                 switch (*state)
  94.                 {
  95.  
  96.                 case TGST_REF:
  97.                     if (!strcmp(nw, ">"))
  98.                         *state = TGST_TAG;
  99.                     break;
  100.  
  101.                 case TGST_QUOTE:
  102.                     if (!strcmp(nw, "'"))
  103.                         *state = TGST_TAG;
  104.                     break;
  105.  
  106.                 case TGST_DQUOTE:
  107.                     if (!strcmp(nw, "\""))
  108.                         *state = TGST_TAG;
  109.                     break;
  110.                 }
  111.             }
  112.             else
  113.             {
  114.                 /* unexpected end of line */
  115.                 hsc_msg_eol(hp);
  116.                 *state = TGST_TAG;      /* go on reading inside tag */
  117.             }
  118.  
  119.             break;
  120.         }
  121.     }
  122.     else
  123.     {
  124.         hsc_msg_eof(hp, "`>' expected");
  125.         *state = TGST_ERR;
  126.     }
  127.  
  128.     return ((BOOL) ((*state == TGST_END) || (*state == TGST_ERR)));
  129. }
  130.  
  131. /*
  132.  * skip_until_eot_args
  133.  *
  134.  * skip until end of tag reached,
  135.  * with user definable status vars
  136.  *
  137.  * params: inpf.....input file
  138.  *         quote....status for quote (TRUE=inside quote)
  139.  *         dquote...status for double quote
  140.  *         argattr..status for quote
  141.  * result: TRUE, if no fatal error
  142.  * errors: return FALSE
  143.  */
  144. BOOL skip_until_eot_state(HSCPRC * hp, BYTE * state, EXPSTR * logstr)
  145. {
  146.     INFILE *inpf = hp->inpf;
  147.  
  148.     while (!eot_reached(hp, state))
  149.         if (logstr)
  150.         {
  151.             app_estr(logstr, infgetcws(inpf));
  152.             app_estr(logstr, infgetcw(inpf));
  153.         }
  154.  
  155.     /* append ">" */
  156.     if (logstr)
  157.     {
  158.         app_estr(logstr, infgetcws(inpf));
  159.         app_estr(logstr, infgetcw(inpf));
  160.     }
  161.  
  162.     return ((BOOL) ! (hp->fatal));
  163. }
  164.  
  165. /*
  166.  * skip_until_eot
  167.  *
  168.  * skip until end of tag reached
  169.  *
  170.  * params: inpf..input file
  171.  * result: TRUE, if no fatal error
  172.  * errors: return FALSE
  173.  */
  174. BOOL skip_until_eot(HSCPRC * hp, EXPSTR * logstr)
  175. {
  176.     BYTE state = TGST_TAG;
  177.  
  178.     return (skip_until_eot_state(hp, &state, logstr));
  179. }
  180.  
  181. /*
  182.  *-----------------
  183.  * skip comment
  184.  *-----------------
  185.  */
  186.  
  187. /*
  188.  * eoc_reched
  189.  *
  190.  * check if end of an hsc-comment is reached
  191.  *
  192.  * params:
  193.  *   inpf...where to read next word from
  194.  *   state..state var; has to be initiales by
  195.  *          calling func with CMST_TEXT
  196.  *   nest...comment netsing counter; has to be
  197.  *          initiales by calling func with 0
  198.  * result: TRUE, if end of comment reached
  199.  */
  200. BOOL eoc_reached(HSCPRC * hp, BYTE * state, LONG * nest)
  201. {
  202.     INFILE *inpf = hp->inpf;
  203.     STRPTR nw = infgetw(inpf);
  204.  
  205.     if (nw)
  206.     {
  207.         switch (*state)
  208.         {
  209.         case CMST_TEXT:
  210.             if (!strcmp(nw, "*"))
  211.                 *state = CMST_STAR;
  212.             else if (!strcmp(nw, "<"))
  213.                 *state = CMST_TAG;
  214.             break;
  215.  
  216.         case CMST_STAR:
  217.             if (!strcmp(nw, "*"))
  218.                 *state = CMST_STAR;
  219.             else if (!strcmp(nw, "<"))
  220.                 *state = CMST_TAG;
  221.             else if (!strcmp(nw, ">"))
  222.                 if (*nest)
  223.                 {
  224.                     (*nest)--;
  225.                     *state = CMST_TEXT;
  226.                 }
  227.                 else
  228.                     *state = CMST_END;
  229.  
  230.             break;
  231.  
  232.         case CMST_TAG:
  233.             if (!strcmp(nw, "<"))
  234.                 *state = CMST_TAG;
  235.             else
  236.             {
  237.                 if (!strcmp(nw, "*"))
  238.                     (*nest)++;
  239.                 *state = CMST_TEXT;
  240.             }
  241.             break;
  242.         }
  243.     }
  244.     else
  245.     {
  246.         hsc_msg_eof(hp, "missing end of comment (\"*>\")");
  247.         *state = CMST_ERR;
  248.     }
  249.  
  250.     return ((BOOL) ((*state == CMST_END) || (*state == CMST_ERR)));
  251. }
  252.  
  253. /*
  254.  * skip_hsc_comment
  255.  *
  256.  * skip text until '*>' occures;
  257.  * nested commets are supported
  258.  *
  259.  */
  260. BOOL skip_hsc_comment(HSCPRC * hp)
  261. {
  262.     BYTE cstate = CMST_TEXT;    /* vars for eoc_reached() */
  263.     LONG cnest = 0;
  264.     BOOL end = FALSE;           /* end of comment reached? */
  265.  
  266.     while (!end && !(hp->fatal))
  267.     {
  268.         end = eoc_reached(hp, &cstate, &cnest);
  269.     }
  270.  
  271.     return ((BOOL) ! (hp->fatal));
  272. }
  273.  
  274. /*
  275.  * skip_until_tag
  276.  *
  277.  * skip everythin, until a specific tag (one of tagstoplist or tagnest)
  278.  * is found.
  279.  *
  280.  * params:
  281.  *  hp hsc-process to work with
  282.  *  tagfound     destination string that will store name of tag that lead
  283.  *               to abortion of skip (eg "$else"); if this string is NULL,
  284.  *               it will be ignored
  285.  *  tagstoplist  list of tags to stop on, sparated with vertical bars `|'
  286.  *               eg. "$else|$elseif"
  287.  *  tagnest      single tag, that maintains a nesting-counter, depending
  288.  *               on wheter it occures as a start-tag or not; if the
  289.  *               nesting-counter is 0 and it occures as a stop-tag, it
  290.  *               will also stop skipping (eg "$if")
  291.  */
  292. #define STATE_TEXT            1 /* normal text */
  293. #define STATE_TAG             2 /* after "<" */
  294. #define STATE_COMMENT         3 /* inside hsc-comment */
  295. #define STATE_COMMENT_STAR    4 /* inside hsc-comment, after "*" */
  296. #define STATE_TAG_STOP        5 /* found tag in stoplist */
  297. #define STATE_SKIP            6 /* inside `skip section' "<|..|>" */
  298. #define STATE_VBAR            7 /* inside `skip section', after "|" */
  299. #define STATE_TAGNAME         8 /* after tagname */
  300. #define STATE_ENDTAGNAME      9 /* after end-tagname */
  301.  
  302. #define STATE_TAGATTR        10 /* parsing tag-attribs */
  303. #define STATE_TAGATTR_EQ     11 /* "=" inside tag */
  304. #define STATE_TAGATTR_DQUOTE 12 /* double quote after "=" inside tag */
  305. #define STATE_TAGATTR_SQUOTE 13 /* single quote after "=" inside tag */
  306. #define STATE_COMMENT_TAG    14 /* found "<" inside comment (nest comment) */
  307.  
  308. #define STATE_EXIT_ERROR_EOF 99 /* unexpected eof */
  309.  
  310. BOOL skip_until_tag(HSCPRC * hp, EXPSTR * tagfound, STRPTR tagstoplist, STRPTR tagnest)
  311. {
  312.     UBYTE state = STATE_TEXT;   /* */
  313.     INFILE *inpf = hp->inpf;    /* input file */
  314.     LONG nesting = 0;           /* tag-nesting */
  315.     LONG nesting_comment = 0;   /* comment-nesting */
  316.     STRPTR nw = NULL;
  317.     BOOL quit = FALSE;          /* flag: exit from skipping */
  318.     EXPSTR *ungetstr = init_estr(32);
  319.  
  320.     clr_estr(tagfound);
  321.  
  322.     do
  323.     {
  324.         /* get next word or tag-id */
  325.         if (state != STATE_TAG)
  326.             nw = infgetw(inpf);
  327.         else
  328.         {
  329.             nw = infget_tagid(hp);
  330.             if (nw)
  331.             {
  332.                 app_estr(ungetstr, infgetcws(inpf));
  333.                 app_estr(ungetstr, infgetcw(inpf));
  334.                 if (strcmp(nw, "/"))
  335.                 {
  336.                     DS(fprintf(stderr, DHLS "start-tag <%s>\n", nw));
  337.                     state = STATE_TAGNAME;      /* tag detected */
  338.                 }
  339.                 else
  340.                 {
  341.                     nw = infget_tagid(hp);
  342.                     DS(fprintf(stderr, DHLS "end-tag </%s>\n", nw));
  343.                     app_estr(ungetstr, infgetcws(inpf));
  344.                     app_estr(ungetstr, infgetcw(inpf));
  345.                     state = STATE_ENDTAGNAME;   /* end-tag detected */
  346.                 }
  347.             }
  348.         }
  349.  
  350.         if (nw)
  351.         {
  352.             switch (state)
  353.             {
  354.  
  355.                 /* check if tag starts */
  356.             case STATE_TEXT:
  357.                 if (!strcmp(nw, "<"))
  358.                 {
  359.                     DS(fprintf(stderr, DHLS "tag\n"));
  360.                     set_estr(ungetstr, nw);
  361.                     state = STATE_TAG;
  362.                 }
  363.                 break;
  364.  
  365.                 /* check which tag it is and how to act */
  366.             case STATE_TAGNAME:
  367.                 {
  368.                     /* check, if nesting-tag should be incr. */
  369.                     if (!upstrcmp(nw, tagnest))
  370.                     {
  371.                         DS(fprintf(stderr, DHLS "nest-tag (%ld)\n", nesting));
  372.                         state = STATE_TAGATTR;
  373.                         nesting++;
  374.                     }
  375.                     /* check, if stop-tag reached */
  376.                     else if (!nesting
  377.                              && strenum(nw, tagstoplist, '|', STEN_NOCASE))
  378.                     {
  379.                         DS(fprintf(stderr, DHLS "stop-tag `%s'\n", nw));
  380.                         set_estr(tagfound, nw);
  381.                         quit = TRUE;
  382.                     }
  383.                     /* check, if commant-tag reached */
  384.                     else if (!strcmp(nw, HSC_COMMENT_STR))
  385.                     {
  386.                         DS(fprintf(stderr, DHLS "comment-tag (0)\n"));
  387.                         state = STATE_COMMENT;
  388.                     }
  389.                     /* any tag; just skip attributes */
  390.                     else
  391.                     {
  392.                         DS(fprintf(stderr, DHLS "any tag\n"));
  393.                         state = STATE_TAGATTR;
  394.                     }
  395.                     break;
  396.                 }
  397.  
  398.             case STATE_ENDTAGNAME:
  399.                 {
  400.                     if (!upstrcmp(nw, tagnest))
  401.                     {
  402.                         if (nesting)
  403.                         {
  404.                             nesting--;
  405.                             DS(fprintf(stderr, DHLS "nest-tag (%ld)\n", nesting));
  406.                         }
  407.                         else
  408.                         {
  409.                             DS(fprintf(stderr, DHLS "nest-tag ending\n"));
  410.                             quit = TRUE;
  411.                         }
  412.                     }
  413.                     else
  414.                         state = STATE_TEXT;     /* no attr for endtag */
  415.  
  416.                     break;
  417.                 }
  418.  
  419.                 /*
  420.                  * process tag attributes
  421.                  */
  422.             case STATE_TAGATTR:
  423.                 {
  424.                     if (!strcmp(nw, "="))
  425.                         state = STATE_TAGATTR_EQ;
  426.                     else if (!strcmp(nw, ">"))
  427.                     {
  428.                         DS(fprintf(stderr, DHLS "back to text\n"));
  429.                         state = STATE_TEXT;
  430.                     }
  431.                     break;
  432.                 }
  433.  
  434.             case STATE_TAGATTR_EQ:
  435.                 {
  436.                     if (!strcmp(nw, "\""))
  437.                     {
  438.                         DS(fprintf(stderr, DHLS "tagarg (double quote)\n"));
  439.                         state = STATE_TAGATTR_DQUOTE;
  440.                     }
  441.                     else if (!strcmp(nw, "'"))
  442.                     {
  443.                         DS(fprintf(stderr, DHLS "tagarg (single quote)\n"));
  444.                         state = STATE_TAGATTR_SQUOTE;
  445.                     }
  446.                     else
  447.                         state = STATE_TAGATTR;
  448.                     break;
  449.                 }
  450.  
  451.             case STATE_TAGATTR_DQUOTE:
  452.                 {
  453.                     if (!strcmp(nw, "\""))
  454.                     {
  455.                         DS(fprintf(stderr, DHLS "end tagarg (double quote)\n"));
  456.                         state = STATE_TAGATTR;
  457.                     }
  458.                     break;
  459.                 }
  460.  
  461.             case STATE_TAGATTR_SQUOTE:
  462.                 {
  463.                     if (!strcmp(nw, "'"))
  464.                     {
  465.                         DS(fprintf(stderr, DHLS "end tagarg (single quote)\n"));
  466.                         state = STATE_TAGATTR;
  467.                     }
  468.                     break;
  469.                 }
  470.  
  471.                 /*
  472.                  * comment processing
  473.                  */
  474.             case STATE_COMMENT:
  475.                 {
  476.                     /* check for <" */
  477.                     if (!strcmp(nw, "<"))
  478.                         state = STATE_COMMENT_TAG;
  479.                     else if (!strcmp(nw, HSC_COMMENT_STR))
  480.                         state = STATE_COMMENT_STAR;
  481.                     break;
  482.                 }
  483.  
  484.             case STATE_COMMENT_TAG:
  485.                 {
  486.                     /* check for comment-nesting */
  487.                     if (!strcmp(nw, HSC_COMMENT_STR))
  488.                     {
  489.                         nesting_comment++;
  490.                         DS(fprintf(stderr, DHLS "comment-tag (%ld)\n", nesting_comment));
  491.                         state = STATE_COMMENT;
  492.                     }
  493.                     else
  494.                         state = STATE_COMMENT;
  495.  
  496.                     break;
  497.                 }
  498.  
  499.             case STATE_COMMENT_STAR:
  500.                 {
  501.                     /* check for end comment */
  502.                     if (!strcmp(nw, ">"))
  503.                         if (nesting_comment)
  504.                         {
  505.                             nesting_comment--;
  506.                             DS(fprintf(stderr, DHLS "end comment-tag (%ld)\n", nesting_comment));
  507.                             state = STATE_COMMENT;
  508.                         }
  509.                         else
  510.                         {
  511.                             DS(fprintf(stderr, DHLS "end comment-tag (%ld)\n", nesting_comment));
  512.                             state = STATE_TEXT;
  513.                         }
  514.                     else
  515.                         state = STATE_COMMENT;
  516.                     break;
  517.                 }
  518.  
  519.                 /*
  520.                  * unhandled tag
  521.                  */
  522.             default:
  523.                 panic("unhandled state");
  524.                 break;
  525.             }
  526.         }
  527.     }
  528.     while (nw && !quit && !(hp->fatal));
  529.  
  530.     if (nw)
  531.     {
  532.         inungets(estr2str(ungetstr), inpf);
  533.     }
  534.     else
  535.     {
  536.         EXPSTR *tagstr = init_estr(0);
  537.  
  538.         set_estr(tagstr, "</");
  539.         app_estr(tagstr, tagnest);
  540.         app_estr(tagstr, "> expected");
  541.         hsc_msg_eof(hp, estr2str(tagstr));
  542.  
  543.         del_estr(tagstr);
  544.     }
  545.  
  546.     del_estr(ungetstr);
  547.  
  548.     return ((BOOL) (nw != NULL));
  549. }
  550.  
  551.